//
// Created by hkkzzxz on 24-8-31.
//

#include <json/json.h>

#include "HttpRouter.h"
#include "AdminController.h"
#include "EmployeeController.h"
#include "UserController.h"
#include "TokenError.h"
#include "JWT.h"
#include "SuperAdminController.h"

HttpRouter::HttpRouter() {
    // 注册路由和处理函数

    // token验证失败
    getRouteMap["/error"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                               http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<TokenError>();
        handler->tokenError(id, httpRequest, httpResponse);
    };

    // GET 方法路由

    // 员工查询今日考勤记录
    getRouteMap["/employee/checkTodayAttendance"] = [](std::string &id,
                                                       http::request<http::dynamic_body> &httpRequest,
                                                       http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->checkTodayAttendance(id, httpRequest, httpResponse);
    };
    // 员工查询所有考勤记录
    getRouteMap["/employee/checkAttendance"] = [](std::string &id,
                                                  http::request<http::dynamic_body> &httpRequest,
                                                  http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->checkAttendance(id, httpRequest, httpResponse);
    };

    // 管理员查询考勤规则
    getRouteMap["/admin/checkAttendanceRules"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                                    http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<AdminController>();
        handler->checkAttendanceRules(data, httpRequest, httpResponse);
    };
    // 管理员查询员工信息
    getRouteMap["/admin/employeeInformation"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                                   http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<AdminController>();
        handler->employeeInformation(data, httpRequest, httpResponse);
    };
    // 管理员查询所有员工考勤情况
    getRouteMap["/admin/checkAttendance"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                               http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<AdminController>();
        handler->checkAttendance(data, httpRequest, httpResponse);
    };
    // 管理员导出考勤报表
    getRouteMap["/admin/exportReport"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                            http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<AdminController>();
        handler->exportReport(data, httpRequest, httpResponse);
    };

    // 超级管理员查询管理员信息
    getRouteMap["/superAdmin/checkAdmin"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                               http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<SuperAdminController>();
        handler->checkAdmin(data, httpRequest, httpResponse);
    };

    // POST方法路由

    // 添加管理员
    postRouteMap["/superAdmin/addAdmin"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                                              http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<SuperAdminController>();
        handler->addAdmin(id, httpRequest, httpResponse);
    };
    //删除管理员
    postRouteMap["/superAdmin/deleteAdmin"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                                                 http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<SuperAdminController>();
        handler->deleteAdmin(id, httpRequest, httpResponse);
    };

    // 添加员工
    postRouteMap["/admin/addEmployee"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                                            http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<AdminController>();
        handler->addEmployee(id, httpRequest, httpResponse);
    };
    // 设置全部考勤规则
    postRouteMap["/admin/setAllAttendanceRules"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                                                      http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<AdminController>();
        handler->setAllAttendanceRules(id, httpRequest, httpResponse);
    };
    // 设置单人考勤规则
    postRouteMap["/admin/setAttendanceRules"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                                                   http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<AdminController>();
        handler->setAttendanceRules(id, httpRequest, httpResponse);
    };
    // 删除员工
    postRouteMap["/admin/deleteEmployee"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                                               http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<AdminController>();
        handler->deleteEmployee(id, httpRequest, httpResponse);
    };
    // 同步（替换）考勤数据
    postRouteMap["/admin/synchronizeData"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                                                http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<AdminController>();
        handler->synchronizeData(id, httpRequest, httpResponse);
    };

    // 修改手机号
    postRouteMap["/employee/modifyPhoneNumber"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                                                     http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->modifyPhoneNumber(id, httpRequest, httpResponse);
    };
    // 修改密码
    postRouteMap["/employee/modifyPassword"] = [](std::string &id, http::request<http::dynamic_body> &httpRequest,
                                                  http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->modifyPassword(id, httpRequest, httpResponse);
    };
    // 上传人脸考勤照片
    postRouteMap["/employee/uploadAttendancePhoto"] = [](std::string &id,
                                                         http::request<http::dynamic_body> &httpRequest,
                                                         http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->uploadAttendancePhoto(id, httpRequest, httpResponse);
    };


    // 不需要token验证
    //获取当前时间
    getRouteMap["/employee/getTime"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                          http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->getTime(data, httpRequest, httpResponse);
    };

    // 员工注册
    postRouteMap["/employee/register"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                            http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->employeeRegister(data, httpRequest, httpResponse);
    };

    // 用户登陆
    postRouteMap["/login"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<UserController>();
        handler->login(data, httpRequest, httpResponse);
    };
    // 用户忘记密码重置密码
    postRouteMap["/employee/forgetPassword"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                                  http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->forgetPassword(data, httpRequest, httpResponse);
    };
    // 生成指纹ID
    postRouteMap["/employee/generateFingerprintID"] = [](std::string &data,
                                                         http::request<http::dynamic_body> &httpRequest,
                                                         http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->generateFingerprintID(data, httpRequest, httpResponse);
    };
    // 指纹考勤
    postRouteMap["/employee/fingerprintAttendance"] = [](std::string &data,
                                                         http::request<http::dynamic_body> &httpRequest,
                                                         http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->fingerprintAttendance(data, httpRequest, httpResponse);
    };
    // 人脸考勤
    postRouteMap["/employee/facialAttendance"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                                    http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->facialAttendance(data, httpRequest, httpResponse);
    };
    // 获取员工姓名
    postRouteMap["/employee/getName"] = [](std::string &data, http::request<http::dynamic_body> &httpRequest,
                                           http::response<http::dynamic_body> &httpResponse) {
        auto handler = std::make_unique<EmployeeController>();
        handler->getName(data, httpRequest, httpResponse);
    };
}

bool HttpRouter::handleAuthorization(http::request<http::dynamic_body> &httpRequest,
                                     http::response<http::dynamic_body> &httpResponse,
                                     const std::string &target, std::string &id) {
    auto it = httpRequest.find("Authorization");
    if (it == httpRequest.end()) {
        std::string error = "error";
        getRouteMap["/error"](error, httpRequest, httpResponse);
        return false;
    }

    std::string token = it->value();
    std::unique_ptr<JWT> jwt = std::make_unique<JWT>();
    Json::Value data = jwt->verify(token);
    id = data["id"].asString();
    std::string identity = data["identity"].asString();

    // 根据身份信息进行路由权限控制
    if ((target.find("/admin/") == 0 && (identity == "admin" || identity == "superAdmin")) ||
        (target.find("/employee/") == 0 && identity == "employee") ||
        (target.find("/superAdmin/") == 0 && identity == "superAdmin")) {
        return true;
    } else {
        getRouteMap["/error"](id, httpRequest, httpResponse);
        return false;
    }
}

void HttpRouter::POSTSelect(http::request<http::dynamic_body> &httpRequest,
                            http::response<http::dynamic_body> &httpResponse) {
    std::string target = httpRequest.target();
    if (target == "/login" || target == "/employee/register"
        || target == "/employee/forgetPassword" || target == "/employee/fingerprintAttendance"
        || target == "/employee/facialAttendance" || target == "/employee/getName"
        || target == "/employee/generateFingerprintID") {
        postRouteMap[target](target, httpRequest, httpResponse);
        return;
    }

    auto it = postRouteMap.find(target);
    // 判断是否有实现方法
    if (it != postRouteMap.end()) {
        std::string id;
        if (handleAuthorization(httpRequest, httpResponse, target, id)) {
            postRouteMap[target](id, httpRequest, httpResponse);
        }
    } else {
        Json::Value root;
        root["code"] = "404";
        root["data"] = "";
        root["message"] = "The requested method is not supported for this resource!";
        std::string jsonStr = root.toStyledString();
        httpResponse.result(http::status::not_found);
        beast::ostream(httpResponse.body()) << jsonStr;
    }

}

void HttpRouter::GETSelect(http::request<http::dynamic_body> &httpRequest,
                           http::response<http::dynamic_body> &httpResponse) {
    std::string target = httpRequest.target();
    if (target == "/employee/getTime") {
        getRouteMap[target](target, httpRequest, httpResponse);
        return;
    }

    auto it = getRouteMap.find(target);
    if (it != getRouteMap.end()) {
        std::string id;
        if (handleAuthorization(httpRequest, httpResponse, target, id)) {
            getRouteMap[target](id, httpRequest, httpResponse);
        }
    } else {
        Json::Value root;
        root["code"] = "404";
        root["data"] = "";
        root["message"] = "The requested method is not supported for this resource!";

        std::string jsonStr = root.toStyledString();
        httpResponse.result(http::status::not_found);
        beast::ostream(httpResponse.body()) << jsonStr;
    }
}
